package queue.impl;

import queue.Queue;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;

/**
 * User: Vitalii Serdiuk
 * Date: 05.12.13 0:40
 */
public class ListQueue<T> implements Queue<T> {
    private Node<T> head;
    private Node<T> tail;
    private int size;

    public ListQueue() {
        tail = head = null;
        size = 0;
    }

    public ListQueue(T element) {
        tail = head = new Node<T>(element);
        size = 1;
    }

    public ListQueue(Node head, Node tail, int size) {
        this.head = head;
        this.tail = tail;
        this.size = size;
    }

    @Override
    public T element() {

        if (head != null && head.getData() != null) {
            return head.getData();
        } else
            throw new NoSuchElementException();
    }

    @Override
    public boolean offer(T t) {
        if (t == null)
            throw new NullPointerException();

        Node<T> newNode = new Node<T>(t);
        if (head == null && tail == null) {
            tail = head = newNode;
        } else {
            tail.setNext(newNode);
            tail.getNext().setPrev(tail);
            tail = newNode;
        }
        size++;
        return true;
    }

    @Override
    public T peek() {
        if (head == null)
            return null;
        else
            return head.getData();
    }

    @Override
    public T poll() {
        if (head == null) return null;
        if(head.getNext()==null){
            T x = head.getData();
            head=tail=null;
            size = 0;
            return x;
        }
        T x = head.getData();
        head = head.getNext();
        head.setPrev(null);
        size--;
        return x;
    }


    @Override
    public T remove() {
        T x = poll();
        if (x == null) throw new NoSuchElementException();
        else return x;
    }

    ///////////////

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return head == null;
    }

    @Override
    public boolean contains(Object o) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Iterator<T> iterator() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Object[] toArray() {
        return new Object[0];  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public <T1> T1[] toArray(T1[] a) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean add(T t) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean remove(Object o) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void clear() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String toString() {
        return "ListQueue{" +
                "head=" + head +
                ", tail=" + tail +
                ", size=" + size +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ListQueue)) return false;

        ListQueue listQueue = (ListQueue) o;

        if (size != listQueue.size) return false;
        if (head != null ? !head.equals(listQueue.head) : listQueue.head != null) return false;
        if (tail != null ? !tail.equals(listQueue.tail) : listQueue.tail != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = head != null ? head.hashCode() : 0;
        result = 31 * result + (tail != null ? tail.hashCode() : 0);
        result = 31 * result + size;
        return result;
    }
}
